using RimWorld;
using RimWorld.Planet;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Verse;

namespace TW_Rainbow_Land
{

    public class GenStep_PlaceItem : GenStep_ScatterThings
    {
        public List<ThingItem> itemsToScatter;

        // 物品堆叠数量范围
        public IntRange stackCountRange = new IntRange(1, 1);
        
        // 每个物品周围的最小检查距离，避免物品过于密集
        public float minDistanceBetweenItems = 5f;
        
        // 在指定半径内最多允许放置多少个同类物品
        public int maxItemsInRadius = 3;
        public float itemCountCheckRadius = 15f;
        
        // 总体生成限制
        public IntRange totalItemsToPlace = new IntRange(1, 5);
        
        // 放置成功率（0-1），用于稀有物品
        public float placementChance = 1f;

        public override int SeedPart => 398176421;

        public override void Generate(Map map, GenStepParams parms)
        {
            Log.Message($"TW111: GenStep_PlaceItem.Generate called for map {map}");
            
            if (ShouldSkipMap(map))
            {
                return;
            }

            usedSpots.Clear();
            int num = CalculateFinalCount(map);
            Log.Message($"TW111: Will attempt to scatter {num} items");
            
            for (int i = 0; i < num; i++)
            {
                if (!TryFindScatterCell(map, out var result))
                {
                    continue;
                }
                
                #if DEBUG
                Log.Message($"TW111: Found scatter cell {result} for item {i + 1}");
                #endif
                ScatterAt(result, map, parms, 1);
            }

            usedSpots.Clear();
        }

        protected override bool ShouldSkipMap(Map map)
        {
            // 检查基本的跳过条件，但不检查 thingDef 相关的
            if (!allowInWaterBiome && map.TileInfo.WaterCovered)
            {
                return true;
            }

            if (onlyOnStartingMap && !map.IsStartingMap)
            {
                return true;
            }

            // 检查物品列表是否为空
            if (itemsToScatter == null || itemsToScatter.Count == 0)
            {
                Log.Warning("GenStep_PlaceItem: itemsToScatter is null or empty, skipping map generation");
                return true;
            }

            return false;
        }

        protected override void ScatterAt(IntVec3 loc, Map map, GenStepParams parms, int stackCount = 1)
        {
            #if DEBUG
            Log.Message($"TW111: GenStep_PlaceItem ScatterAt called at {loc} in {map?.ToString() ?? "null"}");
            #endif
            
            // 检查物品列表是否为空
            if (itemsToScatter == null || itemsToScatter.Count == 0)
            {
                // Log.Message("TW111: itemsToScatter is null or empty");
                return;
            }

            // 检查放置成功率
            if (!Rand.Chance(placementChance))
            {
                return;
            }

            ThingDef selectedDef = SelectRandomThingDef();
            if (selectedDef == null)
            {
                return;
            }

            #if DEBUG
            Log.Message($"TW111: Selected def: {selectedDef.defName}");
            #endif

            // 检查周围是否已有太多相同类型的物品
            if (CountItemsInRadius(loc, map, selectedDef, itemCountCheckRadius) >= maxItemsInRadius)
            {
                return;
            }

            // 检查最小距离
            if (!CheckMinimumDistance(loc, map, minDistanceBetweenItems))
            {
                return;
            }

            // 找到合适的位置放置物品
            IntVec3 spawnPos = loc;
            if (!IsValidPlacementLocation(spawnPos, map))
            {
                // 在附近找一个合适的位置
                bool foundValidPos = false;
                for (int i = 1; i < 9; i++)
                {
                    IntVec3 candidate = loc + GenRadial.RadialPattern[i];
                    if (candidate.InBounds(map) && IsValidPlacementLocation(candidate, map))
                    {
                        spawnPos = candidate;
                        foundValidPos = true;
                        break;
                    }
                }
                
                // 如果还是找不到合适位置，就不放置
                if (!foundValidPos)
                {
                    return;
                }
            }

            // 生成并放置物品
            Thing thing = ThingMaker.MakeThing(selectedDef);
            if (thing != null)
            {
                // 如果物品定义是建筑，则只放置一个
                if (selectedDef.category == ThingCategory.Building)
                {
                    thing.stackCount = 1;
                }
                else
                {
                    // 获取当前选择的 ThingItem 来读取 count 信息
                    ThingItem selectedItem = GetSelectedThingItem(selectedDef);
                    IntRange countRange = GetCountRange(selectedItem);
                    
                    // 设置堆叠数量
                    if (thing.def.stackLimit > 1)
                    {
                        thing.stackCount = countRange.RandomInRange;
                        thing.stackCount = Mathf.Min(thing.stackCount, thing.def.stackLimit);
                    }
                }
                
                #if DEBUG
                Log.Message($"TW111: Successfully spawning {thing} at {spawnPos} in {map}");
                #endif
                GenSpawn.Spawn(thing, spawnPos, map);
            }
        }

        private ThingDef SelectRandomThingDef()
        {
            if (itemsToScatter == null || itemsToScatter.Count == 0)
                return null;

            // 计算总权重
            int totalScore = 0;
            for (int i = 0; i < itemsToScatter.Count; i++)
            {
                totalScore += itemsToScatter[i].score;
            }

            if (totalScore <= 0)
                return null;

            // 生成随机数
            int randomValue = Rand.Range(0, totalScore);

            // 遍历列表，减去score，直到<=0
            for (int i = 0; i < itemsToScatter.Count; i++)
            {
                randomValue -= itemsToScatter[i].score;
                if (randomValue <= 0)
                {
                    return itemsToScatter[i].def;
                }
            }

            // 如果出现意外情况，返回第一个
            return itemsToScatter[0].def;
        }

        /// <summary>
        /// 检查指定位置是否适合放置物品
        /// </summary>
        private bool IsValidPlacementLocation(IntVec3 pos, Map map)
        {
            return pos.InBounds(map) && pos.Standable(map) && pos.GetFirstBuilding(map) == null && !pos.GetThingList(map).Any(t => t.def.category == ThingCategory.Item);
        }

        /// <summary>
        /// 计算指定半径内同类型物品的数量
        /// </summary>
        private int CountItemsInRadius(IntVec3 center, Map map, ThingDef thingDef, float radius)
        {
            int count = 0;
            foreach (IntVec3 cell in GenRadial.RadialCellsAround(center, radius, true))
            {
                if (!cell.InBounds(map))
                    continue;

                List<Thing> thingsAtCell = cell.GetThingList(map);
                for (int i = 0; i < thingsAtCell.Count; i++)
                {
                    if (thingsAtCell[i].def == thingDef)
                    {
                        count++;
                    }
                }
            }
            return count;
        }

        /// <summary>
        /// 检查指定位置周围最小距离内是否有其他物品
        /// </summary>
        private bool CheckMinimumDistance(IntVec3 center, Map map, float minDistance)
        {
            foreach (IntVec3 cell in GenRadial.RadialCellsAround(center, minDistance, false))
            {
                if (!cell.InBounds(map))
                    continue;

                List<Thing> thingsAtCell = cell.GetThingList(map);
                for (int i = 0; i < thingsAtCell.Count; i++)
                {
                    if (thingsAtCell[i].def.category == ThingCategory.Item)
                    {
                        return false; // 找到了物品，距离太近
                    }
                }
            }
            return true; // 没有找到物品，距离足够
        }

        /// <summary>
        /// 根据 ThingDef 找到对应的 ThingItem
        /// </summary>
        private ThingItem GetSelectedThingItem(ThingDef thingDef)
        {
            if (itemsToScatter == null || itemsToScatter.Count == 0)
                return null;

            for (int i = 0; i < itemsToScatter.Count; i++)
            {
                if (itemsToScatter[i].def == thingDef)
                {
                    return itemsToScatter[i];
                }
            }
            return null;
        }

        /// <summary>
        /// 解析 ThingItem 的 count 字符串，返回数量范围
        /// 如果解析失败，返回默认的 1~5
        /// </summary>
        private IntRange GetCountRange(ThingItem item)
        {
            // 如果 item 为空或者 count 为空，使用默认范围
            if (item == null || string.IsNullOrEmpty(item.count))
            {
                return new IntRange(1, 5);
            }

            try
            {
                string countStr = item.count.Trim();
                
                // 检查是否包含 ~ 符号
                if (countStr.Contains("~"))
                {
                    string[] parts = countStr.Split('~');
                    if (parts.Length == 2)
                    {
                        if (int.TryParse(parts[0].Trim(), out int min) && 
                            int.TryParse(parts[1].Trim(), out int max))
                        {
                            return new IntRange(min, max);
                        }
                    }
                }
                else
                {
                    // 如果没有 ~，尝试解析为单个数字
                    if (int.TryParse(countStr, out int single))
                    {
                        return new IntRange(single, single);
                    }
                }
            }
            catch
            {
                // 解析失败，使用默认值
                Log.Warning($"GenStep_PlaceItem: Failed to parse count '{item.count}' for {item.def?.defName}, using default 1~5");
            }

            // 解析失败时的默认值
            return new IntRange(1, 5);
        }
    }

    public class ThingItem
    {
        public ThingDef def;
        public int score;

        public string count; // 用于存储物品数量信息 (采用 50~100 的格式,对建筑无效)
    }
}